package com.och.mrcp.core.mrcp.model;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * MRCPv2消息基类
 * RFC 6787 - Media Resource Control Protocol Version 2 (MRCPv2)
 */
@Data
@Slf4j
public abstract class MrcpMessage {
    
    // MRCP版本 (RFC 6787 Section 6.1)
    protected static final String MRCP_VERSION = "2.0";
    
    // 消息类型 (RFC 6787 Section 6.1)
    public enum MessageType {
        REQUEST,    // 请求消息
        RESPONSE,   // 响应消息
        EVENT       // 事件消息
    }
    
    // 资源类型 (RFC 6787 Section 6.1)
    public enum ResourceType {
        SPEECHSYNTH("speechsynth"),     // 语音合成
        SPEECHRECOG("speechrecog"),     // 语音识别
        RECORDSESSION("recordsession"), // 录音会话
        SPEAKVERIFY("speakverify"),     // 说话人验证
        SPEAKID("speakid");             // 说话人识别
        
        private final String value;
        
        ResourceType(String value) {
            this.value = value;
        }
        
        public String getValue() {
            return value;
        }
        
        public static ResourceType fromString(String value) {
            for (ResourceType type : values()) {
                if (type.value.equalsIgnoreCase(value)) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Unknown resource type: " + value);
        }
    }
    
    // RFC 6787 Section 6.1 - 消息属性
    protected MessageType messageType;
    protected int messageLength;
    protected ResourceType resourceType;
    protected String resourceUri;
    protected String messageId;
    protected String channelIdentifier;
    // MRCPv2 请求状态（用于起始行中的 <request-state>，例如 COMPLETE / IN-PROGRESS）
    protected String requestState;
    
    // RFC 6787 Section 6.2 - 头部字段
    protected Map<String, String> headers = new HashMap<>();
    
    // RFC 6787 Section 6.3 - 消息体
    protected String body;
    
    public MrcpMessage() {
        this.headers = new HashMap<>();
    }
    
    /**
     * 添加头部字段 (RFC 6787 Section 6.2)
     */
    public void addHeader(String name, String value) {
        if (name == null || value == null) {
            throw new IllegalArgumentException("Header name and value cannot be null");
        }
        headers.put(name, value);
    }
    
    /**
     * 获取头部字段值
     */
    public String getHeader(String name) {
        return headers.get(name);
    }
    
    /**
     * 移除头部字段
     */
    public void removeHeader(String name) {
        headers.remove(name);
    }
    
    /**
     * 检查是否包含指定头部
     */
    public boolean hasHeader(String name) {
        return headers.containsKey(name);
    }
    
    /**
     * 获取所有头部字段
     */
    public Map<String, String> getAllHeaders() {
        return new HashMap<>(headers);
    }
    
    // RFC 6787 Section 6.2.1 - 通用头部字段
    
    /**
     * 设置内容类型 (RFC 6787 Section 6.2.1.1)
     */
    public void setContentType(String contentType) {
        addHeader("Content-Type", contentType);
    }
    
    /**
     * 获取内容类型
     */
    public String getContentType() {
        return getHeader("Content-Type");
    }
    
    /**
     * 设置内容长度 (RFC 6787 Section 6.2.1.2)
     */
    public void setContentLength(int length) {
        addHeader("Content-Length", String.valueOf(length));
    }
    
    /**
     * 获取内容长度
     */
    public int getContentLength() {
        String lengthStr = getHeader("Content-Length");
        return lengthStr != null ? Integer.parseInt(lengthStr) : 0;
    }
    
    /**
     * 设置请求ID (RFC 6787 Section 6.2.1.3)
     */
    public void setRequestId(String requestId) {
        if (requestId != null && !requestId.trim().isEmpty()) {
            addHeader("MRCP-Request-ID", requestId);
        }
    }
    
    /**
     * 获取请求ID
     */
    public String getRequestId() {
        return getHeader("MRCP-Request-ID");
    }
    
    /**
     * 设置会话ID (RFC 6787 Section 6.2.1.4)
     */
    public void setSessionId(String sessionId) {
        if (sessionId != null && !sessionId.trim().isEmpty()) {
            addHeader("Session-Id", sessionId);
        }
    }
    
    /**
     * 获取会话ID
     */
    public String getSessionId() {
        return getHeader("Session-Id");
    }
    
    /**
     * 设置状态码 (RFC 6787 Section 6.2.1.5)
     * 注意：不再自动添加MRCP-Status-Code头部，因为客户端不识别
     */
    public void setStatusCode(int statusCode) {
        // 不再自动添加头部，因为客户端不识别MRCP-Status-Code
        // addHeader("MRCP-Status-Code", String.valueOf(statusCode));
        log.debug("Status code set to: {} (header not added)", statusCode);
    }
    
    /**
     * 获取状态码
     */
    public int getStatusCode() {
        String codeStr = getHeader("MRCP-Status-Code");
        return codeStr != null ? Integer.parseInt(codeStr) : 0;
    }
    
    /**
     * 设置请求状态 (RFC 6787 Section 6.2.1.6)
     * 注意：不再自动添加MRCP-Request-State头部，因为客户端不识别
     */
    public void setRequestState(String state) {
        // 不再添加头部，使用内部字段以便在起始行输出
        this.requestState = state;
        log.debug("Request state set to: {} (stored internally)", state);
    }
    
    /**
     * 获取请求状态
     */
    public String getRequestState() {
        return requestState;
    }
    
    /**
     * 设置完成原因 (RFC 6787 Section 6.2.1.7)
     * 注意：不再自动添加MRCP-Completion-Cause头部，因为客户端不识别
     */
    public void setCompletionCause(String cause) {
        // 不再自动添加头部，因为客户端不识别MRCP-Completion-Cause
        // addHeader("MRCP-Completion-Cause", cause);
        log.debug("Completion cause set to: {} (header not added)", cause);
    }
    
    /**
     * 获取完成原因
     */
    public String getCompletionCause() {
        return getHeader("MRCP-Completion-Cause");
    }
    
    /**
     * 设置通道标识符 (RFC 6787 Section 6.2.1.8)
     */
    public void setChannelIdentifier(String identifier) {
        if (identifier != null && !identifier.trim().isEmpty()) {
            addHeader("Channel-Identifier", identifier);
        }
    }
    
    /**
     * 获取通道标识符
     */
    public String getChannelIdentifier() {
        return getHeader("Channel-Identifier");
    }
    
    /**
     * 设置资源标识符 (RFC 6787 Section 6.2.1.9)
     */
    public void setResourceIdentifier(String identifier) {
        if (identifier != null && !identifier.trim().isEmpty()) {
            addHeader("Resource-Identifier", identifier);
        }
    }
    
    /**
     * 获取资源标识符
     */
    public String getResourceIdentifier() {
        return getHeader("Resource-Identifier");
    }
    
    /**
     * 设置输入类型 (RFC 6787 Section 6.2.1.10)
     */
    public void setInputType(String inputType) {
        if (inputType != null && !inputType.trim().isEmpty()) {
            addHeader("Input-Type", inputType);
        }
    }
    
    /**
     * 获取输入类型
     */
    public String getInputType() {
        return getHeader("Input-Type");
    }
    
    /**
     * 设置输出类型 (RFC 6787 Section 6.2.1.11)
     */
    public void setOutputType(String outputType) {
        addHeader("Output-Type", outputType);
    }
    
    /**
     * 获取输出类型
     */
    public String getOutputType() {
        return getHeader("Output-Type");
    }
    
    /**
     * 设置语音活动检测 (RFC 6787 Section 6.2.1.12)
     */
    public void setVoiceActivityDetection(boolean enabled) {
        addHeader("Voice-Activity-Detection", enabled ? "true" : "false");
    }
    
    /**
     * 获取语音活动检测状态
     */
    public boolean getVoiceActivityDetection() {
        String vad = getHeader("Voice-Activity-Detection");
        return "true".equalsIgnoreCase(vad);
    }
    
    /**
     * 设置置信度阈值 (RFC 6787 Section 6.2.1.13)
     */
    public void setConfidenceThreshold(float threshold) {
        addHeader("Confidence-Threshold", String.valueOf(threshold));
    }
    
    /**
     * 获取置信度阈值
     */
    public float getConfidenceThreshold() {
        String threshold = getHeader("Confidence-Threshold");
        return threshold != null ? Float.parseFloat(threshold) : 0.0f;
    }
    
    /**
     * 设置敏感度 (RFC 6787 Section 6.2.1.14)
     */
    public void setSensitivity(float sensitivity) {
        addHeader("Sensitivity", String.valueOf(sensitivity));
    }
    
    /**
     * 获取敏感度
     */
    public float getSensitivity() {
        String sensitivity = getHeader("Sensitivity");
        return sensitivity != null ? Float.parseFloat(sensitivity) : 0.0f;
    }
    
    /**
     * 设置速度 (RFC 6787 Section 6.2.1.15)
     */
    public void setSpeed(float speed) {
        addHeader("Speed", String.valueOf(speed));
    }
    
    /**
     * 获取速度
     */
    public float getSpeed() {
        String speed = getHeader("Speed");
        return speed != null ? Float.parseFloat(speed) : 1.0f;
    }
    
    /**
     * 设置音量 (RFC 6787 Section 6.2.1.16)
     */
    public void setVolume(float volume) {
        addHeader("Volume", String.valueOf(volume));
    }
    
    /**
     * 获取音量
     */
    public float getVolume() {
        String volume = getHeader("Volume");
        return volume != null ? Float.parseFloat(volume) : 1.0f;
    }
    
    /**
     * 设置语言 (RFC 6787 Section 6.2.1.17)
     */
    public void setLanguage(String language) {
        addHeader("Language", language);
    }
    
    /**
     * 获取语言
     */
    public String getLanguage() {
        return getHeader("Language");
    }
    
    /**
     * 设置语音 (RFC 6787 Section 6.2.1.18)
     */
    public void setVoice(String voice) {
        addHeader("Voice", voice);
    }
    
    /**
     * 获取语音
     */
    public String getVoice() {
        return getHeader("Voice");
    }
    
    /**
     * 检查消息是否有效 (RFC 6787 Section 6.1)
     */
    public abstract boolean isValid();
    
    /**
     * 将消息编码为字符串 (RFC 6787 Section 6.4)
     */
    public abstract String encode();
    
    /**
     * 获取消息类型描述
     */
    public abstract String getMessageTypeDescription();
    
    /**
     * 生成MRCPv2消息格式 (RFC 6787 Section 6.4)
     */
    protected String generateMrcpMessage() {
        StringBuilder sb = new StringBuilder();
        
        // 第一行：MRCP版本 消息长度 资源类型 资源URI 消息ID 通道标识符
        sb.append("MRCP/").append(MRCP_VERSION).append(" ");
        sb.append(messageLength).append(" ");
        sb.append(resourceType != null ? resourceType.getValue() : "").append(" ");
        sb.append(resourceUri != null ? resourceUri : "").append(" ");
        sb.append(messageId != null ? messageId : "").append(" ");
        sb.append(channelIdentifier != null ? channelIdentifier : "").append("\r\n");
        
        // 头部字段
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\r\n");
        }
        
        // 空行
        sb.append("\r\n");
        
        // 消息体
        if (body != null && !body.isEmpty()) {
            sb.append(body);
        }
        
        return sb.toString();
    }
    
    @Override
    public String toString() {
        return String.format("MrcpMessage{type=%s, resourceType=%s, messageId=%s, headers=%d, bodyLength=%d}",
                messageType, resourceType, messageId, headers.size(), body != null ? body.length() : 0);
    }
}
